const { ccclass, property } = cc._decorator;

@ccclass
export default class bezierTest extends cc.Component {

    @property(cc.Node)
    startNode: cc.Node = null;
    @property(cc.Node)
    ctrlNode: cc.Node = null;
    @property(cc.Node)
    ctrlNode2: cc.Node = null;
    @property(cc.Node)
    ctrlNode3: cc.Node = null;
    @property(cc.Node)
    endNode: cc.Node = null;

    ctx: cc.Graphics = null;
    anchorPoint: cc.Vec2 = null;
    _level: number = 2;
    get level() {
        return this._level;
    }
    set level(v) {
        if (v == 1) return;
        this._level = v;
        this.ctrlNode3.active = true;
        this.endNode.active = true;
        if (v == 2) {
            this.ctrlNode3.active = false;
            this.endNode.active = false;
        } else if (v == 3) {
            this.endNode.active = false;
        }
    }
    onLoad() {
        window['mainScript'] = this;
        this.level = 2;
        // this.anchorPoint = this.ctrlNode.position = this.endNode.position;
        if (!this.ctx) {
            let ctxNode = new cc.Node('ctxNode');
            ctxNode.parent = cc.director.getScene();
            let ctx = ctxNode.addComponent(cc.Graphics);
            this.ctx = ctx;
        }
        console.log('注册')
        this.registerEvent(this.startNode)
        this.registerEvent(this.ctrlNode)
        this.registerEvent(this.ctrlNode2)
        this.registerEvent(this.ctrlNode3)
        this.registerEvent(this.endNode)
    }

    changeLevel(touch) {
        let name = touch.target.name;
        let num = name.split('_')[1];
        this.level = num;
    }
    registerEvent(node) {
        node.on(cc.Node.EventType.TOUCH_START, this.touchMove, this);
        node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMove, this);
        node.on(cc.Node.EventType.TOUCH_END, this.touchMove, this);
        node.on(cc.Node.EventType.TOUCH_CANCEL, this.touchMove, this);
    }

    touchMove(touch) {
        console.log('touchMove', touch.target.name);

        touch.target.position = touch.getLocation();
        // this.ctrlNode.y = this.startNode.y + (this.endNode.y - this.startNode.y) / 2;
        // console.log('this.ctrlNode.y', this.ctrlNode.y)
        this.draw();
    }

    draw() {
        let points = [];
        let length = 40;
        let level = this._level;
        this.ctx.clear();
        this.ctx.fillColor = cc.color(255, 255, 0);
        let wpos: cc.Vec2 = null;
        for (let i = 0; i < length; i++) {
            if (level == 2) {
                let p0 = this.startNode.parent.convertToWorldSpaceAR(this.startNode.position)
                let p1 = this.ctrlNode.parent.convertToWorldSpaceAR(this.ctrlNode.position)
                let p2 = this.ctrlNode2.parent.convertToWorldSpaceAR(this.ctrlNode2.position)
                let t = i / length;
                wpos = this.bezier2(p0, p1, p2, t)

            } else if (level == 3) {
                let p0 = this.startNode.parent.convertToWorldSpaceAR(this.startNode.position)
                let p1 = this.ctrlNode.parent.convertToWorldSpaceAR(this.ctrlNode.position)
                let p2 = this.ctrlNode2.parent.convertToWorldSpaceAR(this.ctrlNode2.position)
                let p3 = this.ctrlNode3.parent.convertToWorldSpaceAR(this.ctrlNode3.position)
                let t = i / length;
                wpos = this.bezier3(p0, p1, p2, p3, t)

            } else if (level == 4) {
                let p0 = this.startNode.parent.convertToWorldSpaceAR(this.startNode.position)
                let p1 = this.ctrlNode.parent.convertToWorldSpaceAR(this.ctrlNode.position)
                let p2 = this.ctrlNode2.parent.convertToWorldSpaceAR(this.ctrlNode2.position)
                let p3 = this.ctrlNode3.parent.convertToWorldSpaceAR(this.ctrlNode3.position)
                let p4 = this.endNode.parent.convertToWorldSpaceAR(this.endNode.position)
                let t = i / length;
                wpos = this.bezier4(p0, p1, p2, p3, p4, t)

            }
            console.log('level', level)
            points.push(wpos);
            this.ctx.circle(wpos.x, wpos.y, 5)
            this.ctx.stroke();
            this.ctx.fill();
        }
        // console.log('point', points)
    }

    // 二阶贝塞尔
    bezier2(p0, p1, p2, t) {
        let t1 = (1 - t) * (1 - t);
        let t2 = 2 * t * (1 - t);
        let t3 = t * t;
        return p0.mul(t1).add(p1.mul(t2)).add(p2.mul(t3));
    }
    // 三阶贝塞尔
    bezier3(p0, p1, p2, p3, t) {
        let t0 = (1 - t) * (1 - t) * (1 - t);
        let t1 = 3 * t * (1 - t) * (1 - t);
        let t2 = 3 * t * t * (1 - t);
        let t3 = t * t * t;
        return p0.mul(t0).add(p1.mul(t1)).add(p2.mul(t2)).add(p3.mul(t3));
    }

    // 四阶贝塞尔
    bezier4(p0, p1, p2, p3, p4, t) {
        let t0 = (1 - t) * (1 - t) * (1 - t) * (1 - t);
        let t1 = 4 * t * (1 - t) * (1 - t) * (1 - t);
        let t2 = 4 * t * t * (1 - t) * (1 - t);
        let t3 = 4 * t * t * t * (1 - t);
        let t4 = t * t * t * t;
        return p0.mul(t0).add(p1.mul(t1)).add(p2.mul(t2)).add(p3.mul(t3)).add(p4.mul(t4));
    }

}
